<template>
  <div class="rich-text-editor">
    <!-- 工具栏 -->
    <Toolbar
      class="editor-toolbar"
      :editor="editorRef"
      :defaultConfig="toolbarConfig"
      :mode="mode"
    />
    
    <!-- 编辑器 -->
    <Editor
      class="editor-content"
      :style="{ height: editorHeight }"
      v-model="valueHtml"
      :defaultConfig="editorConfig"
      :mode="mode"
      @onCreated="handleCreated"
      @onChange="handleChange"
      @onDestroyed="handleDestroyed"
      @onFocus="handleFocus"
      @onBlur="handleBlur"
    />
  </div>
</template>

<script setup lang="ts">
import '@wangeditor/editor/dist/css/style.css'
import { onBeforeUnmount, ref, shallowRef, watch, computed, nextTick, inject } from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import type { IToolbarConfig, IEditorConfig } from '@wangeditor/editor'
import { Boot, type IDomEditor } from "@wangeditor/editor";

// 组件属性定义
interface Props {
  name: string
  modelValue?: string
  placeholder?: string
  height?: string | number
  mode?: 'default' | 'simple'
  disabled?: boolean
  maxLength?: number
  excludeKeys?: string[]
  includeKeys?: string[]
}

// 自定义上传事件
interface Emits {
  (e: 'update:modelValue', value: string): void
  (e: 'change', editor: IDomEditor): void
  (e: 'focus', editor: IDomEditor): void
  (e: 'blur', editor: IDomEditor): void
  (e: 'created', editor: IDomEditor): void
  (e: 'upload-image', file: File, insertFn: (url: string) => void): void
  (e: 'upload-video', file: File, insertFn: (url: string) => void): void
}

const props = withDefaults(defineProps<Props>(), {
  name: '',
  modelValue: '',
  placeholder: '请输入内容...',
  height: '400px',
  mode: 'default',
  disabled: false,
  maxLength: 10000,
  excludeKeys: () => [],
  includeKeys: () => []
})

const emit = defineEmits<Emits>()

// 编辑器实例，必须用 shallowRef
const editorRef = shallowRef<IDomEditor>()

// 内容 HTML
const valueHtml = ref('')

// 计算编辑器高度
const editorHeight = computed(() => {
  if (typeof props.height === 'number') {
    return `${props.height}px`
  }
  return props.height
})

// 注入祖先组件提供的函数
const handleUploadFromAncestor = inject<((flag: boolean, name: string) => void)>('handleUpload', () => {});
const fileUrl = inject<any>('fileUrl', null);
const chooseName = inject<any>('chooseName', null);
const type = ref('');

// 保存光标位置（保存选区的起始和结束位置）
const savedSelection = ref<{
  anchor: { path: number[], offset: number },
  focus: { path: number[], offset: number }
} | null>(null);

const handleUpload = () => {
  if (!handleUploadFromAncestor) {
    console.warn('Upload: handleUpload function not provided by ancestor');
    return;
  }

  // 保存当前光标位置
  if (editorRef.value) {
    try {
      const selection = editorRef.value.selection;
      if (selection) {
        // 保存选区的详细信息
        savedSelection.value = {
          anchor: {
            path: [...selection.anchor.path],
            offset: selection.anchor.offset
          },
          focus: {
            path: [...selection.focus.path],
            offset: selection.focus.offset
          }
        };
      }
    } catch (error) {
      console.warn('保存光标位置失败:', error);
    }
  }

  handleUploadFromAncestor(true, props.name + '_' + type.value);
}

// 监听文件上传结果
watch(
  () => [fileUrl?.value, chooseName?.value],
  ([newFileUrl, newChooseName]: [string | null | undefined, string | null | undefined]) => {
    // 只有当 chooseName 匹配当前组件的 name 时才更新
    if (!newFileUrl || !newChooseName || newChooseName !== props.name + '_' + type.value) {
      return;
    }

    if (!editorRef.value) {
      return;
    }

    // 恢复光标位置并聚焦
    nextTick(() => {
      if (!editorRef.value) return;

      try {
        // 先聚焦编辑器
        editorRef.value.focus();

        // 如果有保存的光标位置，尝试恢复
        if (savedSelection.value) {
          try {
            // 使用 select 方法恢复选区
            editorRef.value.select(savedSelection.value);
          } catch (error) {
            console.warn('恢复光标位置失败，使用默认位置:', error);
          }
        }
      } catch (error) {
        console.warn('聚焦编辑器失败:', error);
      }

      if (type.value === 'img') {
        // 使用最通用的方法插入内容 - 直接插入HTML
        const url = newFileUrl
        const html = `<img src="${url}" alt="图片" style="max-width: 100%;">`
        editorRef.value?.dangerouslyInsertHtml(html)
      } else {
        // 使用最通用的方法插入内容 - 直接插入HTML
        const url = newFileUrl
        const html = `<video src="${url}" controls style="max-width: 100%;"></video>`
        editorRef.value?.dangerouslyInsertHtml(html)
      }

      // 清除保存的光标位置
      savedSelection.value = null;
    });
  },
  { immediate: false }
)

// 自定义菜单类
class CustomImageMenu {
  title: string;
  tag: string;
  iconSvg: string;
  
  constructor() {
    this.title = '上传图片'
    this.tag = 'button'
    this.iconSvg = '<svg viewBox="0 0 1024 1024"><path d="M959.877 128l0.123 0.123v767.775l-0.123 0.122H64.102l-0.122-0.122V128.123l0.122-0.123h895.775zM960 64H64C28.795 64 0 92.795 0 128v768c0 35.205 28.795 64 64 64h896c35.205 0 64-28.795 64-64V128c0-35.205-28.795-64-64-64zM832 288.01c0 53.023-42.988 96.01-96.01 96.01s-96.01-42.987-96.01-96.01S682.967 192 735.99 192 832 234.988 832 288.01zM896 832H128V704l224.01-384 256 320h64l224.01-192z"></path></svg>' // 可以使用原有的图片图标
  }
  
  isActive(): boolean {
    return false;
  }
  getValue(): string | boolean {
    return "";
  }
  isDisabled(): boolean {
    return false;
  }
  exec() {
    // 触发隐藏的文件选择器
    nextTick(() => {
      console.log('点击了自定义上传图片菜单')
      type.value = 'img'
      handleUpload()
    })
  }
}

class CustomVideoMenu {
  title: string
  tag: string
  iconSvg: string
  
  constructor() {
    this.title = '上传视频'
    this.tag = 'button'
    this.iconSvg = '<svg viewBox="0 0 1024 1024"><path d="M981.184 160.096C837.568 139.456 678.848 128 512 128S186.432 139.456 42.816 160.096C15.296 267.808 0 386.848 0 512s15.264 244.16 42.816 351.904C186.464 884.544 345.152 896 512 896s325.568-11.456 469.184-32.096C1008.704 756.192 1024 637.152 1024 512s-15.264-244.16-42.816-351.904zM384 704V320l320 192-320 192z"></path></svg>' // 可以使用原有的视频图标
  }
  
  getValue(): string | boolean {
    return ''
  }
  
  isActive(): boolean {
    return false
  }
  
  isDisabled(): boolean {
    return false
  }
  
  exec() {
    // 触发隐藏的文件选择器
    nextTick(() => {
      type.value = 'video'
      handleUpload()
    })
  }
}

// 工具栏配置 - 正确排除原始按钮并添加自定义按钮
const toolbarConfig: Partial<IToolbarConfig> = {
  toolbarKeys: [
    // 菜单 key
    "headerSelect",
    "bold", // 加粗
    "italic", // 斜体
    "through", // 删除线
    "underline", // 下划线
    "color", // 文字颜色
    "fontSize", // 字体大小
    "lineHeight", // 行高
    "delIndent", // 缩进
    "indent", // 增进
    "divider", // 分割线
    "insertTable", // 插入表格
    "justifyCenter", // 居中对齐
    "justifyJustify", // 两端对齐
    "justifyLeft", // 左对齐
    "justifyRight", // 右对齐
    "undo", // 撤销
    "redo", // 重做
    "clearStyle", // 清除格式
    "codeBlock" //代码块
  ],
}

// 编辑器配置
const editorConfig: Partial<IEditorConfig> = {
  placeholder: props.placeholder,
  readOnly: props.disabled,
  maxLength: props.maxLength,
  MENU_CONF: {}
}

// 编辑器创建后注册自定义菜单
const handleCreated = (editor: IDomEditor) => {
  editorRef.value = editor
  // 注册自定义菜单
  const CustomImageMenuButton = {
    key: "CustomImageMenu", // 定义 menu key ：要保证唯一、不重复（重要）
 
    factory() {
      return new CustomImageMenu(); // 把 `YourMenuClass` 替换为你菜单的 class
    }
  };
  const CustomVideoMenuButton = {
    key: "CustomVideoMenu", // 定义 menu key ：要保证唯一、不重复（重要）
 
    factory() {
      return new CustomVideoMenu(); // 把 `YourMenuClass` 替换为你菜单的 class
    }
  };
  Boot.registerMenu(CustomImageMenuButton);
  Boot.registerMenu(CustomVideoMenuButton);
  toolbarConfig.insertKeys = {
    index: 0,
    keys: ['CustomImageMenu', 'CustomVideoMenu']
  }
  emit('created', editor)
}

// 组件销毁时，也及时销毁编辑器
onBeforeUnmount(() => {
  const editor = editorRef.value
  if (editor == null) return
  editor.destroy()
})

// 监听外部传入的内容变化
watch(
  () => props.modelValue,
  (newVal: string) => {
    if (newVal !== valueHtml.value) {
      valueHtml.value = newVal || ''
    }
  },
  { immediate: true }
)

const handleChange = (editor: IDomEditor) => {
  emit('update:modelValue', valueHtml.value)
  emit('change', editor)
}

const handleDestroyed = () => {
  editorRef.value = undefined
}

const handleFocus = (editor: IDomEditor) => {
  emit('focus', editor)
}

const handleBlur = (editor: IDomEditor) => {
  emit('blur', editor)
}

// 动态导入 WangEditor 组件
// let Editor: any = null
// let Toolbar: any = null

// // 只在客户端加载编辑器
// onMounted(async () => {
//   if (typeof window !== 'undefined') {
//     try {
//       // 动态导入编辑器组件
//       const wangEditor = await import('@wangeditor/editor-for-vue')
//       Editor = wangEditor.Editor
//       Toolbar = wangEditor.Toolbar
      
//       // 导入 CSS
//       await import('@wangeditor/editor/dist/css/style.css')
      
//       // 标记编辑器已加载
//       editorLoaded.value = true
//     } catch (error) {
//       console.error('编辑器加载失败:', error)
//     }
//   }
// })

// 暴露编辑器实例和方法
defineExpose({
  editor: editorRef,
  getHtml: () => valueHtml.value,
  getText: () => editorRef.value?.getText() || '',
  isEmpty: () => editorRef.value?.isEmpty() || true,
  clear: () => editorRef.value?.clear(),
  focus: () => editorRef.value?.focus(),
  blur: () => editorRef.value?.blur(),
  disable: () => editorRef.value?.disable(),
  enable: () => editorRef.value?.enable()
})
</script>

<style scoped>
.rich-text-editor {
  border: 1px solid var(--color-border-2);
  border-radius: 6px;
  overflow: hidden;
  background: #fff;
  min-height: 300px; /* 确保有最小高度 */
}

.editor-toolbar {
  border-bottom: 1px solid var(--color-border-2);
  background: var(--color-bg-1);
}

.editor-content {
  overflow-y: auto;
}

/* 编辑器加载状态 */
.editor-loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 300px;
  color: #666;
}

.loading-spinner {
  width: 40px;
  height: 40px;
  border: 4px solid rgba(0, 0, 0, 0.1);
  border-radius: 50%;
  border-top-color: #3498db;
  animation: spin 1s ease-in-out infinite;
  margin-bottom: 15px;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

/* 编辑器内容样式 */
:deep(.w-e-text-container) {
  background: #fff;
}

:deep(.w-e-text-placeholder) {
  color: var(--color-text-3);
}

/* 工具栏样式调整 */
:deep(.w-e-toolbar) {
  border-bottom: none;
  background: transparent;
}

:deep(.w-e-bar-item) {
  height: 30px;
}

:deep(.w-e-bar-divider) {
  height: 30px;
}

:deep(.w-e-toolbar .w-e-bar-item button) {
  border-radius: 4px;
  transition: all 0.2s;
}

:deep(.w-e-toolbar .w-e-bar-item button:hover) {
  background: var(--color-fill-2);
}

:deep(.w-e-toolbar .w-e-bar-item button.active) {
  background: rgb(var(--primary-1));
  color: rgb(var(--primary-6));
}

/* 禁用状态样式 */
.rich-text-editor.disabled {
  background: var(--color-bg-2);
  cursor: not-allowed;
}

.rich-text-editor.disabled :deep(.w-e-text-container) {
  background: var(--color-bg-2);
  cursor: not-allowed;
}
</style>